/**
 * Project Name:spring-cloud-pilot File Name:RestartApplicationListener.java Package Name:org.spring.cloud.pilot
 * Date:2019年10月18日上午10:28:36 Copyright (c) 2019, dengqian37@126.com All Rights Reserved.
 *
 */

package org.spring.cloud.pilot.listener;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;

import org.spring.cloud.pilot.filewatch.FileSystemWatcher;
import org.springframework.boot.context.event.ApplicationFailedEvent;
import org.springframework.boot.context.event.ApplicationPreparedEvent;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.boot.context.event.ApplicationStartingEvent;
import org.springframework.cloud.context.environment.EnvironmentChangeEvent;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.core.Ordered;

import com.google.common.base.Strings;

/**
 * ClassName:RestartApplicationListener <br/>
 * Function: TODO ADD FUNCTION. <br/>
 * Reason: TODO ADD REASON. <br/>
 * Date: 2019年10月18日 上午10:28:36 <br/>
 * 
 * @author dengqian
 * @version
 * @since JDK 1.8
 * @see
 */
public class RestartApplicationListener implements ApplicationListener<ApplicationEvent>, Ordered {

    private int order = HIGHEST_PRECEDENCE;
    
    private Thread shutdownHook;

    private static final String ENABLED_PROPERTY = "spring.devtools.restart.enabled";
    private ApplicationPreparedEvent event;
    
    
    private  ApplicationEventPublisher eventPublisher;


    private ConfigurableApplicationContext context;

    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        if (event instanceof ApplicationStartingEvent) {
            onApplicationStartingEvent((ApplicationStartingEvent)event);
        }
        if (event instanceof ApplicationPreparedEvent) {
            onApplicationPreparedEvent((ApplicationPreparedEvent)event);
        }
        
        if (event instanceof ApplicationReadyEvent) {
            onApplicationReadyEvent((ApplicationReadyEvent)event);
        }
        if ( event instanceof ApplicationFailedEvent) {
            // Restarter.getInstance().finish();
        }
        if (event instanceof ApplicationFailedEvent) {
            onApplicationFailedEvent((ApplicationFailedEvent)event);
        }
        
        if (event instanceof ContextRefreshedEvent) {
            onApplicationRefreshedEvent((ContextRefreshedEvent)event);
        }

    }

    private void onApplicationRefreshedEvent(ContextRefreshedEvent event) {
        // It's too early to use the Spring environment but we should still allow
        // users to disable restart using a System property.
        String enabled = System.getProperty(ENABLED_PROPERTY);
        if (enabled == null || Boolean.parseBoolean(enabled)) {
        } else {
            // Restarter.disable();
        }
    }
    
    private void onApplicationReadyEvent(ApplicationReadyEvent event) {
        // It's too early to use the Spring environment but we should still allow
        // users to disable restart using a System property.
//        String enabled = System.getProperty(ENABLED_PROPERTY);
//        System.out.println("[[p[pl[lp");

        
        if (this.event.getApplicationContext().getParent() != null) {


        }
        

        
        
    }
    
    private void onApplicationStartingEvent(ApplicationStartingEvent event) {
        // It's too early to use the Spring environment but we should still allow
        // users to disable restart using a System property.
//        String enabled = System.getProperty(ENABLED_PROPERTY);
        
        
       
        

        
        
    }

    private void onApplicationPreparedEvent(ApplicationPreparedEvent event) {
        this.event = event;
        if (this.context == null) {
            this.context = this.event.getApplicationContext();
//            this.context.publishEvent(new PromoteChangeEvent(null));

        }
        // Restarter.getInstance().prepare(event.getApplicationContext());
    }

    private void onApplicationFailedEvent(ApplicationFailedEvent event) {
        // Restarter.getInstance().remove(event.getApplicationContext());
    }

    @Override
    public int getOrder() {
        return this.order;
    }

    /**
     * Set the order of the listener.
     * 
     * @param order the order of the listener
     */
    public void setOrder(int order) {
        this.order = order;
    }

    public void registerShutdownHook() {
        if (this.shutdownHook == null) {
            // No shutdown hook registered yet.
            this.shutdownHook = new Thread() {
                @Override
                public void run() {
                    try {
                        System.out.println("addShutdownHook");
                        if (isOSWindows()) {
                            System.out.println("Windows");

                            // exeCmd = "cmd.exe /C start startZuulServer.bat";
                            try {
                                Thread.sleep(1000L);
                            } catch (InterruptedException ex) {
                                Thread.currentThread().interrupt();
                            }
                            final Process process = Runtime.getRuntime()
                                .exec(new String[] {"cmd", "/c", "java -jar spring-config-client-0.0.1.jar"});

                            printMessage(process.getInputStream());
                            printMessage(process.getErrorStream());
                            int value = process.waitFor();
                            System.out.println(value);

                        } else {
                            // exeCmd = "/bin/sh -c startWeb.sh";
                            System.out.println("linux");

                            // String command = "find " + source.getRoute() + " -name '" + source.getName();
                            //
                            Process process = Runtime.getRuntime()
                                .exec(new String[] {"/bin/sh", "-c", "java -jar spring-config-client-0.0.1.jar"});
                            printMessage(process.getInputStream());
                            printMessage(process.getErrorStream());
                            int value = process.waitFor();
                            System.out.println(value);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            };
            Runtime.getRuntime().addShutdownHook(this.shutdownHook);
        }
    }

    private static void printMessage(final InputStream input) {
        new Thread(new Runnable() {
            public void run() {

                Reader reader = new InputStreamReader(input);
                BufferedReader bf = new BufferedReader(reader);
                String line = null;
                try {
                    while ((line = bf.readLine()) != null) {
                        System.out.println(line);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    public static boolean isOSWindows() {
        String osName = System.getProperty("os.name");
        if (Strings.isNullOrEmpty(osName)) {
            return false;
        }
        return osName.startsWith("Windows");
    }

}
